<template>
  <div>
    <h1>图片处理：</h1>
    <div class="part part-1">
      <h2>图片展示：上传图片文件获取url的方式：</h2>
      <div class="context">
        <p>方法1：使用window.URL.createObjectURL(file)创建blob临时url</p>
        <p>方法2：input选择图片，FileReader的readAsDataURL读取图片转为base64并展示图片,</p>
        <p>方法3：base64也可以作为展示</p>
      </div>
      <input type="file" ref="file1"><br>
      <el-button @click="imgFileToUrlByURL">URL.createObjectURL</el-button>
      <el-button @click="imgFileToUrlByFileReader">FileReader</el-button>
      <el-button @click="imgFileToBase64ByCanvas">base64Canvas</el-button>
      <el-button @click="clearUrl">清空url</el-button>
      <br>
      <img :src="url" alt="" width="200" height="100">
    </div>

    <div class="part part-2">
      <h2>图片压缩：图片文件压缩到指定大小以内</h2>
      <input type="file" ref="file2"><br>
      <el-button @click="compress">压缩</el-button>
      <div class="context">
        压缩前：{{part2.originSize}}kb , 压缩后： {{part2.compressSize}}kb
      </div>
      <br>
      <div class="compare-box">
        <img class="origin-img" :src="part2.originUrl" alt="">
        <img class="compress-img" :src="part2.compressUrl" alt="">
        <div class="line">
          <div class="btn"></div>
        </div>
      </div>
    </div>

    <div class="part part-4">
      <h3>base64图片转blob对象，然后blob对象通过File转文件对象，最后通过formData实现可上传</h3>
      <pre>
        <code></code>
      </pre>
    </div>

    <div class="part part-5">
      <h3>图片压缩:file->base64</h3>
      <input type="file" ref="file5" @change="compress5">
      <div>
        <p>原本：</p>
        <p>大小：{{part5.orgin.size}}kb</p>
        <img :src="part5.orgin.url" alt="">
      </div>
      <div>
        <p>压缩后：</p>
        <p>大小：{{part5.compress.size}}kb</p>
        <img :src="part5.compress.url" alt="">
      </div>
    </div>


  </div>
</template>

<script>
  export default {
    name: "imageDeal",
    data() {
      return {
        // part-1
        url: '',

        // part-2
        part2: {
          originUrl: null,
          originSize: 0,
          compressUrl: null,
          compressSize: 0
        },

        part5: {
          orgin: {
            url: '',
            size: 0
          },
          compress: {
            url: '',
            size: 0
          }
        },

        part6: {
          origin: {
            url: '',
            size: 0
          },
          compress: {
            url: '',
            size: 0
          }
        },

        name: 'clw',
        name2: '0'
      }
    },
    methods: {
      // 图片展示
      clearUrl() {
        this.url = null;
      },
      imgFileToUrlByURL() {
        const file = this.$refs.file1.files[0];
        this.url = window.URL.createObjectURL(file)
      },
      imgFileToUrlByFileReader() {
        const file = this.$refs.file1.files[0];
        const reader = new FileReader();
        reader.onload = (e) => {
          this.url = e.target.result;
        };
        reader.readAsDataURL(file);
      },
      imgFileToBase64ByCanvas() {
        const file = this.$refs.file1.files[0];
        const reader = new FileReader();
        reader.onload = (e) => {
          console.log(e)
          this.url = e.currentTarget.result
        };
        reader.readAsArrayBuffer(file)
      },

      // base64的图片大小
      base64ImgSize(base64) { // 计算base64的图片大小
        const bytes = base64.split(',')[1];
        return (bytes.length * .75).toFixed(2)
      },

      // 图片压缩
      compress() {
        const file = this.$refs.file2.files[0];
        const url =  window.URL.createObjectURL(file);
        const img = new Image();
        img.src = this.part2.originUrl = url;
        img.crossOrigin = 'Anonymous'; // 如果存在跨域，需要配置此处
        const type = `image/jpeg`; // 因为要采用canvas的quality质量压缩，且canvas的质量压缩仅支持jpeg格式，所以如此配置
        img.onload = (e) => {
          // 先计算原本图片的base64大小
          const canvas = document.createElement('canvas');
          const ctx = canvas.getContext('2d');
          const w = e.currentTarget.width;
          const h = e.currentTarget.height;
          canvas.width = w;
          canvas.height = h;
          ctx.drawImage(img, 0, 0, w, h);
          const originBase64 = canvas.toDataURL(type, 1);

          // 计算压缩到指定大小的比例，Math.ceil() 四舍五入向上舍
          const originSize = this.part2.originSize = this.base64ImgSize(originBase64)/1024;
          const scale = Math.ceil(Math.sqrt(Math.ceil(originSize / 30))); // 获取如果要压缩到30kb要压缩多少倍

          // 清空画布以及重新设计宽高
          ctx.clearRect(0, 0, w, h);
          const w2 = parseFloat(Math.ceil(w/scale * 100)/100);
          const h2 = parseFloat(Math.ceil(h/scale * 100)/100);
          canvas.width = w2;
          canvas.height = h2;
          ctx.drawImage(img, 0, 0, w2, h2);
          const compressBase64 = this.part2.compressUrl = canvas.toDataURL(type, 0.1);
          const compressSize = this.part2.compressSize = this.base64ImgSize(compressBase64)/1024;
        }
      },


      imgFileToBlob(e) {
        const file = e.currentTarget.files[0]; // 获取文件对象
        const url = window.URL.createObjectURL(file); // 将文件对象转化为url
        const img = new Image();
        img.src = url;
        img.onload = (event) => {
          const canvas = document.createElement('canvas');
          const ctx = canvas.getContext('2d');
          const w = event.currentTarget.width;
          const h = event.currentTarget.height;
          ctx.width = w;
          ctx.height = h;
          ctx.drawImage(img, 0, 0, w, h);
          canvas.toBlob((result) => {
            console.log(result)
          }, 'image/jpeg', 1)
        }
      },
      // async compress() {
      //   // if (!this.imgUrl || !isUrl(this.imgUrl)) {
      //   //   return this.$message('url格式错误')
      //   // }
      //   /**
      //    * 设计思路：
      //    * 第一步：url转可进行压缩的图片（图片压缩一般将图片弄到画布上，然后缩小宽高比）
      //    * 第二步：获取图片大小，获取希望压缩的图片大小，计算压缩倍数
      //    * 第三步：进行压缩，
      //    * 第四步：获取压缩后的图片，并转为希望转出的格式，默认base64
      //    *
      //    * 文件对象转图片地址：const ulr = window.URL.createObjectURL(fileObj)
      //    *
      //    * url转图片：const image = new Image(); image.src=url; image.onload = function() {}
      //    * */
      //   const image = new Image();
      //   image.src = this.imgUrl;
      //   image.onload = (e) => {
      //     debugger
      //     // 获取图片宽高
      //     let w = this.img.width = e.currentTarget.width;
      //     let h = this.img.height = e.currentTarget.height;
      //     const canvas = document.createElement('canvas');
      //     const ctx = canvas.getContext('2d');
      //     canvas.width = w;
      //     canvas.height = h;
      //     ctx.drawImage(image, 0, 0, w, h);
      //     const base64 = canvas.toDataURL('image/png', 1);
      //     this.img.url = base64;
      //   }
      //   debugger
      //   const res = await this.imageUrlToFile(this.imgUrl)
      //   console.log(res)
      // },
      imageUrlToFile(url) {
        // 通过get请求图片，设置返回参数格式为blob格式，获取图片文件对象，从而计算图片体积
        return new Promise((res, rej) => {
          let blob = null;
          let xhr = new XMLHttpRequest();
          xhr.open('get', url);
          xhr.setRequestHeader('Accept', 'image/jpeg');
          xhr.responseType = 'blob';
          xhr.onload = () => {
            blob = xhr.response;
            let imgFile = new File([blob], `${new Date().getTime()}.png`, { type: 'image/jpeg' });
            res(imgFile)
          };
          xhr.onerror = (err) => {
            rej(err)
          };
          xhr.send()
        })
      },

      // part-4
      base64ToFile() {
        const bytes = window.atob(base64.split(',')[1]); // 去掉base64的头
        const ab = new ArrayBuffer(bytes.length);
        const ia = new Uint8Array(ab);
        for(let i =0,l=bytes.length; i<l; i++) {
          ia[i] = bytes.charCodeAt(i)
        }
        return new Blob([ab], { type: 'image/png' })
      },

      // part-5
      compress5() {
        const file = this.$refs.file5.files[0];
        this.part5.orgin.size = file.size/1024;
        const type = file.type;
        const url =  window.URL.createObjectURL(file);
        this.part5.orgin.url = url;

        const scale = Math.sqrt(file.size / (30*1024)).toFixed(2); // 获取如果要压缩到30kb要压缩多少倍
        const img = new Image();
        img.src = url;
        img.onload = (e) => {
          const canvas = document.createElement('canvas');
          const ctx = canvas.getContext('2d');
          const w = e.currentTarget.width;
          const h = e.currentTarget.height;
          const width = parseFloat((w/scale).toFixed(3));
          const height = parseFloat((h/scale).toFixed(3))
          // canvas.width = width
          canvas.width = w
          // canvas.height = height
          canvas.height = h
          // ctx.clearRect(0, 0, width, height);
          ctx.clearRect(0, 0, w, h);
          // ctx.drawImage(img, 0, 0, width, height);
          ctx.drawImage(img, 0, 0, w, h);
          debugger
          const base64 = canvas.toDataURL(type, 1)
          this.part5.compress.url = base64;
          this.part5.compress.size = this.base64ImgSize(base64)/1024;
        }
      },




    }
  }
</script>

<style scoped lang="scss">
.compare-box{
  box-sizing: border-box;
  position: relative;
  width: 100%;
  overflow: hidden;
  .origin-img{
    display: block;
    height: 100%;
    -o-object-fit: cover;
    object-fit: cover;
    position: absolute;
    top: 0;
    width: 100%;
    clip: rect(auto, 385px, auto, auto);
  }
  .compress-img{
    display: block;
    height: auto;
    width: 100%;
  }
  .line{
    position: absolute;
    top: 0;
    left: 385px;
    width: 2px;
    height: 100%;
    background: #ffffff;
    .btn{
      width: 20px;
      height: 20px;
      position: absolute;
      top: 50%;
      left: -9px;
      border-radius: 50%;
      background: #fff;
    }
  }
}
</style>
